import {
  Component,
  ContentChildren,
  ElementRef,
  EventEmitter,
  Input,
  OnInit,
  Output,
  QueryList,
  ViewChild,
  ViewChildren,
  ViewContainerRef
} from '@angular/core';
import {ActionType, ButtonSizeType, ButtonType, CacheKey, WindowType} from '../enums';
import {DhlCommonComponent} from '../dhlCommonComponent';
import {DhlTitleComponent} from './titles/title/dhl-title.component';
import {FieldComponent} from './custom-field/field.component';
import {FormUtil} from '../../../utils/form-util';
import {ObjectUtil} from '../../../utils/object-util';
import {DhlButtonComponent} from '../button/normal/dhl-button.component';


/**
 * domain：                      指定domain
 * datas：                       列表数据
 * showAdd:                      是否启用新增
 * showEdit：                    是否启用修改
 * showExport = {                是否启用导出
 *    fileName: 导出文件名字
 *    trailDate: 文件名是否添加时间戳
 * }
 * showDelete：                   是否启用删除
 * showSelectDelete:              是否启用多选删除
 * showBatchDelete：              是否启用批量删除
 * showBatchImport：              是否启用批量导入
 * showCheck                      是否启用多选
 * customField：                  是否启用自定义字段
 * fixHead：                      固定头几列
 * fixTail:                       固定尾几列
 * showFields=['tile1','title2']  指定显示的列
 * checkedDatas=[]                选中某几行
 * disabledData                   设置不可选的行
 * params                         查询时候指定params
 * maxHeight                      表格最大的高度
 * formConfig = {
 *   formComponent:               弹窗的组件
 *   formWidth:                   弹窗的宽度
 *   formData:                    弹窗内容的初始化数据
 *   formParams:                  弹窗get请求参数
 *   formTitle:                   弹窗标题
 *   formType:                    弹窗类型    window 或 drawer
 * }
 *
 *
 *
 *
 *
 */
@Component({
  selector: 'dhl-table',
  templateUrl: './dhl-table.component.html',
})
export class DhlTableComponent extends DhlCommonComponent implements OnInit {


  @Input() tableCode;
  uploadPath;
  tableDomain;
  actions = [];
  titles = [];
  sizeOptions = [10, 50, 100, 200, 1000];
  loading = false;
  @Input() total;
  pageIndex;
  pageSize = 10;

  defaultPageLength = 10;

  @Input() set defaultPageSize(value) {
    this.pageSize = value;
    this.defaultPageLength = value;
  }

  editRowObj
  editRowIndex = -1;
  editValue;
  editCol;
  dictionaryValue;
  hiddenSpan = false;
  hiddenInput = true;
  hiddenSelect = true;

  dictionaryRowObj;
  dictionaryRowIndex = -1;
  dictionaryCol;
  indeterminate = false;
  showAction = false;
  gray = ButtonType.GRAY;
  default = ButtonSizeType.DEFAULT;
  sizeType = ButtonSizeType.SMALL;
  deleteType = ButtonType.DANGER;
  actionWidth;
  scroll = {};
  showDownloadImportLog = false;
  downloadLogPath;
  addBtnLoading = false;
  updateBtnLoading = [];
  actionBtnLoading = {};
  defaultParams;
  extraParams = {};
  isCheckAll = false;
  isDisableAll = false;
  isShowExport = false;
  exportLoading = false;
  batchLoading = false;
  batchDeleteLoading = false;
  batchImportLoading = false;
  showTop = true;
  sortType;
  btnTypeLink = ButtonType.LINK;
  exportFileConfig;
  disableExport = true;
  disableBatchDelete = true;
  batchDeleteBtn = [
    {
      name: '下载模板',
      click: () => {
        this.requestService.download(`${this.domain}/batchdeltemplate`);
      }
    },
    {
      name: '上传',
      click: () => {
        this.uploadParams = {...this.defaultParams};
        this.uploadPath = `${this.domain}/batchdel`;
        $('button', this.uploadEleRef.nativeElement).trigger('click');
      }
    }
  ];
  batchImportBtn = [
    {
      name: '下载模板',
      click: () => {
        this.requestService.download(`${this.domain}/template`);
      }
    },
    {
      name: '全字段更新',
      click: () => {
        this.uploadParams = {uploadType: 'all', ...this.defaultParams};
        this.uploadPath = `${this.domain}/import`;
        $('button', this.batchImportEleRef.nativeElement).trigger('click');
      }
    }
  ];

  isShowExportPerm = true;
  showBatchImportPerm = true;
  showSelectDeletePerm = true;
  showBatchDeletePerm = true;
  showAddPerm = true;
  showEditPerm = true;
  showDeletePerm = true;
  uploadParams = {};
  @Input() showBatchImport = false;
  @Input() showSelectDelete = false;
  @Input() showBatchDelete = false;
  @Input() showAdd = true;
  @Input() showEdit = true;
  @Input() showDelete = true;
  @Input() showCheck = false;
  @Input() customField = false;
  @ContentChildren(DhlTitleComponent, {descendants: true}) titlesComponent!: QueryList<DhlTitleComponent>;
  @ContentChildren(DhlButtonComponent, {descendants: true}) topButtonComponent!: QueryList<DhlButtonComponent>;
  @ViewChild('dhltableConfig', {static: true, read: ElementRef}) dhltableConfig: ElementRef;
  @ViewChild('dhltable', {static: true, read: ElementRef}) dhltable: ElementRef;
  @ViewChild('dhltableHead', {static: true, read: ElementRef}) dhltableHead: ElementRef;
  @ViewChild('dhltableBody', {static: true, read: ElementRef}) dhltableBody: ElementRef;
  @ViewChild('dhlTableTopAction', {static: true, read: ElementRef}) dhlTableTopAction: ElementRef;
  @ViewChild('uploadEleRef', {static: true, read: ElementRef}) uploadEleRef: ElementRef;
  @ViewChild('batchImportEleRef', {static: true, read: ElementRef}) batchImportEleRef: ElementRef;

  @ViewChildren('inputTemplate', {read: ViewContainerRef}) templateList: QueryList<ViewContainerRef>;

  @Input() queryLocationRef: ElementRef;

  @Output() checkAll = new EventEmitter();
  @Output() checkChange = new EventEmitter();
  @Output() fieldChange = new EventEmitter();

  @Input() menu = {code: ''};
  @Input() datalist;
  @Input() fields;
  showFieldsValues;

  showFields(value) {
    setTimeout(() => {
      if (ObjectUtil.isHaveValue(value)) {
        this.showFieldsValues = value;
        $(`dhl-title[dataKey]`, this.dhltableConfig.nativeElement).each((index, item) => {
          $(item).attr('show', 'false');
          value.forEach((i, y) => {
            if (i == $(item).attr('dataKey')) {
              $(item).attr('show', 'true');
              return;
            }
          });
        });
      }
      this.initTitleTag();
    }, 50);
  };

  @Input() checkedDatas = [];

  @Input() set maxHeight(value) {
    if (value) {
      this.scroll = {...this.scroll, y: `${value}px`};
    }
  };

  @Input() set datas(value) {
    if (value && ObjectUtil.isArray(value) && ObjectUtil.isObject(value[0])) {
      this.datalist = value;
      this.checkIsCheckAll();
    } else {
      this.datalist = [];
    }
  };

  get datas() {
    return this.datalist;
  }


  @Input() set disabledData(value) {
    if (value && this.datas) {
      this.datas.forEach(item => {
        item.disabled = false;
        item.checked = false;
      });
      if (ObjectUtil.isArray(value) && value.length > 0) {
        const ids = ',' + value.map(item => item[this.primaryKey]).reduce((x, y) => x + ',' + y) + ',';
        if (this.datas) {
          this.datas.forEach(item => {
            if (ids.indexOf(',' + item[this.primaryKey] + ',') > -1) {
              item.disabled = true;
              item.checked = true;
            }
          });
        }
        this.checkedDatas.forEach(item => {
          if (ids.indexOf(',' + item[this.primaryKey] + ',') > -1) {
            item.disable = true;
            item.checked = true;
          }
        });
        this.checkedDatas = [...this.checkedDatas];
      }
      this.checkIsCheckAll();
    }
  };

  @Input() set notDisabledData(value) {
    if (value) {
      if (ObjectUtil.isArray(value) && value.length > 0) {
        const ids = ',' + value.map(item => item[this.primaryKey]).reduce((x, y) => x + ',' + y) + ',';
        if (this.datas) {
          this.datas.forEach(item => {
            if (ids.indexOf(',' + item[this.primaryKey] + ',') > -1) {
              item.disabled = false;
              item.checked = false;
            }
          });
        }

        const newCheckedDatas = [];
        this.checkedDatas.forEach(item => {
          if (ids.indexOf(',' + item[this.primaryKey] + ',') < 0) {
            item.disable = true;
            item.checked = true;
            newCheckedDatas.push(item);
          }
        });
        this.checkedDatas = newCheckedDatas;
      }
    }
  }

  @Input() set domain(value) {
    if (this.tableDomain) {
      this.tableDomain = value;
      this.datalist = [];
      this.freshTable();
    } else {
      this.tableDomain = value;
    }
  };

  get domain() {
    return this.tableDomain;
  }

  @Input() primaryKey = 'id';

  formConfigParams = {
    formComponent: {},
    formWidth: 800,
    formData: {},
    formParams: {},
    formTitle: '',
    formType: WindowType.WINDOWS
  };

  @Input() set formConfig(value) {
    this.formConfigParams = {...this.formConfigParams, ...value};
  };

  get formConfig() {
    return this.formConfigParams;
  }

  @Input() set params(value) {
    let flag = false;
    if (ObjectUtil.isNotEmpty(this.defaultParams)) {
      flag = true;
    }
    this.defaultParams = value;
    if (flag) {
      this.freshTable();
    }
  };

  @Input() fixHead = 1;
  @Input() fixTail = 0;

  @Input() set showExport(v) {
    this.isShowExport = true;
    this.exportFileConfig = v;
  };


  initPermission() {
    this.activeRouter.queryParams.subscribe(({m_c}) => {
      if (m_c) {
        let menuCode = m_c;
        const activeMenu = this.cacheService.getItem(CacheKey.ACTIVE_MENU);
        const menus = this.cacheService.getItem(CacheKey.MENUS);

        if (menus[m_c] && menus[m_c].length == 1) {
          menuCode = activeMenu.code;
        } else if (this.menu) {
          menuCode = this.menu.code;
        }


        this.showAddPerm = this.permissionService.isHasPermission(menuCode, ActionType.ADD);
        this.showEditPerm = this.permissionService.isHasPermission(menuCode, ActionType.UPDATE);
        this.showDeletePerm = this.permissionService.isHasPermission(menuCode, ActionType.DELETE);
        this.isShowExportPerm = this.permissionService.isHasPermission(menuCode, ActionType.EXPORT);
        this.showSelectDeletePerm = this.permissionService.isHasPermission(menuCode, ActionType.SELECT_DELETE);
        this.showBatchDeletePerm = this.permissionService.isHasPermission(menuCode, ActionType.BATCH_DELETE);
        this.showBatchImportPerm = this.permissionService.isHasPermission(menuCode, ActionType.BATCH_IMPORT);
      }
    });

  }

  initQuery() {
    setTimeout(() => {
      const params = this.queryLocationRef ? FormUtil.getData(this.queryLocationRef.nativeElement) : {};
      const requestParams = {length: this.pageSize, ...this.defaultParams, ...this.extraParams, ...params};
      if (this.domain) {
        this.reset();
        this.loading = true;
        this.requestService.get(`${this.domain}/page/${this.pageIndex}`, requestParams).subscribe((data) => {
          this.loading = false;
          if (data) {
            const {datas, total} = data;
            datas.forEach(item => {
              for (const checkItem of this.checkedDatas) {
                if (item[this.primaryKey] == checkItem[this.primaryKey]) {
                  item.checked = checkItem.checked;
                  item.disabled = checkItem.disabled;
                }
              }
            });
            this.datas = datas;
            this.total = total;
            if (datas.length > 0) {
              this.drawCustomView();
            }
          }
        });
      }
    }, 50);

  }

  reset() {
    this.pageIndex = 1;
    this.pageSize = this.defaultPageLength;
  }

  ngOnInit() {
    this.initPermission();
    this.initQuery();
    if (!this.showFieldsValues) {
      this.initTitle();
    }
    this.initTitleShowEvent();

    this.initShowTitle();

    setTimeout(() => {     // 等待页面渲染200毫秒，不然一些dom读取不到
      this.initAction();
      this.initTopAction();
      this.initConfigDiv();
      this.checkDisableBtn();

    }, 200);


    const projectCode = this.cacheService.getItem(CacheKey.ACTIVE_PROJECT);
    if (!ObjectUtil.isHaveValue(projectCode) || projectCode != 'rpmp') {
      this.batchImportBtn.push(
        {
          name: '字段更新',
          click: () => {
            this.uploadParams = {uploadType: 'part', ...this.defaultParams};
            this.uploadPath = `${this.domain}/import`;
            $('button', this.batchImportEleRef.nativeElement).trigger('click');
          }
        });
    }


  }

  initConfigDiv() {
    if (this.domain) {
      $(this.dhltableConfig.nativeElement).attr('domain', this.domain);
    }

    this.resetBtnLoading();

    $(this.dhltable.nativeElement).parents('div.dhl-table').data('uploadBtnLoading', (name, value) => {

      if (name && ObjectUtil.isNumber(value)) {
        for (let index = 0; index < this.actionBtnLoading[name].length; index++) {
          this.actionBtnLoading[name][index] = false;
        }

        if (value >= 0) {
          this.actionBtnLoading[name][value] = true;
        }

      }

    });

  }

  initTitle() {
    if (this.fields) {
      this.initTitleConfig();
    } else {
      setTimeout(() => {
        this.initTitleTag();
      }, 50);
    }
  }

  initTitleTag() {
    const fields = $('dhl-titles[show="true"] dhl-title', this.dhltableConfig.nativeElement)
      .filter((index, item) => ObjectUtil.isUndefined($(item).attr('show')) ? true : ObjectUtil.strToBoolean($(item).attr('show')));
    const titleArray = [];
    const widthData = this.initWidthArray(fields);

    const titleWidthArray = widthData[0];
    this.actionWidth = widthData[1];

    const sumWidth = [...widthData[0], widthData[1]].reduce((a, b) => a + b);

    this.scroll = {...this.scroll, x: `${sumWidth}px`};

    const showCheck = this.showCheck;
    const beforeTotalSum = this.beforeTotalSum;
    const afterTotalSum = this.afterTotalSum;
    const headFix = this.fixHead < 0 ? 1 : this.fixHead;
    const tailFix = this.fixTail < 0 ? 0 : this.fixTail;


    let titleStr = '';
    fields.each((index, item) => {
      titleStr += $(item).attr('dataKey') + ',';
    });

    const titleComponents = this.titlesComponent.filter(({tempRef}) => titleStr.indexOf($(tempRef.nativeElement).parent().attr('dataKey') + ',') > -1);


    fields.each(function (index) {
      const o = {
        template: [],
        name: '',
        valueKey: '',
        dataKey: '',
        sort: false,
        show: true,
        headfixed: '',
        tailfiexd: '',
        width: '',
        align: '',
        edit: false,
        toolTip: undefined,
        dicCode: undefined,
        onClick: undefined
      };

      const titleComponent = titleComponents.filter((p, j) => j == index)[0];
      const eleComponent = titleComponent.viewComponent;
      const onClickFun = titleComponent.onClick;

      o.name = $(this).attr('name');
      o.dataKey = eleComponent ? '' : $(this).attr('dataKey');
      o.valueKey = $(this).attr('dataKey');
      o.align = ObjectUtil.isUndefined($(this).attr('align')) ? 'center' : $(this).attr('align');
      o.sort = ObjectUtil.isUndefined($(this).attr('sort')) ? false : true;
      o.edit = ObjectUtil.isUndefined($(this).attr('edit')) ? false : true;
      o.toolTip = $(this).attr('toolTip');
      o.onClick = onClickFun.observers.length > 0 ? (obj) => {
        titleComponent.onClick.emit(obj);
      } : undefined;
      o.dicCode = $(this).attr('dicCode') ? $(this).attr('dicCode') : undefined;
      o.headfixed = index == 0 ? (showCheck ? '40px' : '0px') : (index < headFix ? `${beforeTotalSum(showCheck, titleWidthArray, index)}px` : '');
      o.tailfiexd = fields.length - 1 - index < tailFix ? `${afterTotalSum([...widthData[0], widthData[1]], index)}px` : '';
      o.width = `${titleWidthArray[showCheck ? index + 1 : index]}px`;
      titleArray.push(o);
    });

    this.titles = titleArray;
  }

  initTitleConfig() {
    this.titles = this.fields.map(item => ({
      name: item.name,
      dataKey: item.code,
      align: 'center',
      sort: false
    }));
  }


  beforeTotalSum(showCheck, titleWidthArray, i) {
    const j = showCheck ? i + 1 : i;
    return titleWidthArray.filter((item, index) => index < j).reduce((a, b) => a + b);
  }

  afterTotalSum(titleWidthArray, i) {
    return titleWidthArray.filter((item, index) => index > i).reduce((a, b) => a + b);
  }

  initWidthArray(fields) {
    const widthArray = fields.map((x, item) => $(item).attr('name')).map((index, item) => item.length * 40).get();
    fields.each((index, item) => {
        const fieldEle = item;
        if (!ObjectUtil.isUndefined($(fieldEle).attr('width'))) {
          widthArray[index] = ObjectUtil.strToNumber($(item).attr('width'));
        }
      }
    );

    const actions = $('dhl-actions dhl-action', this.dhltableConfig.nativeElement);
    let actionWidth = actions.length == 0 ? 100 :
      actions
        .map((index, item) => $(item).attr('name').length * 10)
        .get()
        .reduce((a, b) => a + b + 50) + 120;


    if (this.showEdit) {
      actionWidth += 66;
    }
    if (this.showDelete) {
      actionWidth += 66;
    }

    const headTitleWidthArray = this.showCheck ? [40, ...widthArray] : widthArray;

    return [headTitleWidthArray, actionWidth];


  }


  initTitleShowEvent() {

    setTimeout(() => {
      $('dhl-title', this.dhltableConfig.nativeElement).on('showTitleEvent', (obj, {key, value, dicCode}) => {
        $(`dhl-title[dataKey="${key}"]`, this.dhltableConfig.nativeElement)
          .attr('dicCode', dicCode)
          .attr('show', value);
        this.initTitle();
      });
      $('dhl-titles', this.dhltableConfig.nativeElement).on('showTitlesEvent', (obj, {ele, show}) => {
        this.initTitle();
      });
    }, 50);

  }


  initAction() {
    const $actions = $('dhl-actions dhl-action', this.dhltableConfig.nativeElement);
    $actions.each((i, item) => {
      if ($('button', $(item)).length > 0) {
        // @ts-ignore
        this.actions.push($(item));
      }
    });

    if ((this.showEdit && this.showEditPerm) || (this.showDelete && this.showDeletePerm) || this.actions.length > 0) {
      this.showAction = true;
    }

  }


  initTopAction() {
    const internal = setInterval(() => {
      if (this.dhlTableTopAction) {

        for (const action of this.topButtonComponent) {
          action.queryParams = this.defaultParams;
        }


        clearInterval(internal);
        const topActions = $('dhl-top-actions', this.dhltableConfig.nativeElement);
        $('.table-top-action', $(this.dhlTableTopAction.nativeElement)).append(topActions);
        if (this.customField || this.showAdd || this.showSelectDelete || this.isShowExport || topActions.length > 0) {
          this.showTop = true;
        } else {
          this.showTop = false;
        }
      }
    }, 50);
  }

  initShowTitle() {
    if (this.customField) {
      const tCode = ObjectUtil.isNotEmpty(this.tableCode) ? this.tableCode : this.menu.code;
      this.requestService.get(`common/getfields`, {tableCode: tCode}).subscribe(data => {
        if (data) {
          this.showFields(data);
        }
      });
    }
  }

  pageSizeChange(length) {
    this.pageSize = length;
    this.pageIndex = 1;
    this.freshTable();
  }

  pageIndexChange(index) {
    this.pageIndex = index;
    this.freshTable();
  }

  sortChange() {
    const orderField = this.titles
      .filter(title => ObjectUtil.isHaveValue(title.sortType))
      .map(title => title.valueKey + ' ' + (title.sortType == 'descend' ? 'desc' : 'asc'));
    this.extraParams = {...this.extraParams, orderBy: orderField};
    this.freshTable();
  }

  checkedChange(obj, index) {
    if (obj.checked) {
      this.checkedDatas.push(obj);
    } else {
      this.checkedDatas = this.checkedDatas.filter(item => item[this.primaryKey] != obj[this.primaryKey]);
    }


    this.checkIsCheckAll();
    this.checkDisableBtn();
    this.checkChange.emit({row: obj, index, checkedDatas: this.checkedDatas});
  }

  checkIsCheckAll() {
    if (this.datas && this.datas.length > 0) {
      const noCheckedLength = this.datas.filter(item => !item.checked).length;
      const noDisableLength = this.datas.filter(item => !item.disabled).length;
      if (noCheckedLength > 0) {
        this.isCheckAll = false;
      } else {
        this.isCheckAll = true;
      }
      if (noDisableLength > 0) {
        this.isDisableAll = false;
      } else {
        this.isDisableAll = true;
      }

    } else {
      this.isCheckAll = false;
      this.isCheckAll = false;
    }
  }

  checkedAll() {
    this.isCheckAll = !this.isCheckAll;
    const ids = this.checkedDatas.length > 0 ? ',' + this.checkedDatas.map(item => item[this.primaryKey]).reduce((x, y) => x + ',' + y) + ',' : ',';

    if (this.isCheckAll) { //新增
      this.datas.forEach(item => {
        item.checked = this.isCheckAll;
        if (ids.indexOf(',' + item[this.primaryKey] + ',') < 0) {
          this.checkedDatas.push(item);
        }
      });
    } else { //删除
      const newCheckRows = [];
      this.datas.forEach(item => {
        item.checked = this.isCheckAll;
        if (ids.indexOf(',' + item[this.primaryKey] + ',') < 0) {
          newCheckRows.push(item);
        }
      });
      this.checkedDatas = newCheckRows;
    }

    this.checkDisableBtn();
    this.checkAll.emit(this.checkedDatas);
  }

  private checkDisableBtn() {

    for (const action of this.topButtonComponent) {
      action.checkedRow = this.checkedDatas;
      if (action.checkAvailable) {
        if (this.checkedDatas.length > 0) {
          action.disabled = false;
        } else {
          action.disabled = true;
        }
      } else {
        action.disabled = false;
      }
    }

    if (this.checkedDatas.length > 0) {
      this.disableBatchDelete = false;
      this.disableExport = false;
    } else {
      this.disableBatchDelete = true;
      this.disableExport = true;
    }
  }


  clearCheckedData() {
    this.checkedDatas = [];
    for (const action of this.topButtonComponent) {
      action.checkedRow = [];
    }
  }

  export() {
    let params = this.queryLocationRef ? FormUtil.getData(this.queryLocationRef.nativeElement) : {};
    params['checkedIds'] = this.checkedDatas.map(item => item[this.primaryKey]);
    params['titles'] = this.titles.map(({name, valueKey}) => valueKey + '|' + name);
    params = {...params, ...this.exportFileConfig};
    this.exportLoading = true;
    this.requestService.get(`${this.domain}/export`, params).subscribe(obj => {
      this.exportLoading = false;
      if (obj) {
        this.requestService.download(`${this.domain}/downloadexcel`, {filePath: obj});
      }
    });
  }

  add() {
    if (this.domain) {
      this.addBtnLoading = true;
      this.requestService.get(`${this.domain}/get/-1`, this.formConfig.formParams).subscribe(data => {
        this.addBtnLoading = false;
        if (data) {
          const params = {};
          for (const key of Object.keys(data)) {
            const value = data[key];
            if (value) {
              params[key] = value;
            }
          }
          const formConfig = {
            submitUrl: `${this.domain}/save`,
            component: this.formConfig.formComponent,
            data: {...this.formConfig.formData, ...params},
            width: this.formConfig.formWidth,
            title: '新建',
            okText: '创建',
            afterOk: () => {
              this.freshTable();
            }
          };
          if (this.formConfig.formType == WindowType.WINDOWS) {
            this.windowService.openWindow(formConfig);
          } else {
            if (this.formConfig.formType == WindowType.DRAWER) {
              this.windowService.openDrawer(formConfig);
            }
          }
        }
      });
    } else {
      this.messageService.error('请配置dhl-table的domain参数');
    }

  }

  batchDelete() {
    const ids = this.checkedDatas.map(item => item[this.primaryKey]);
    this.batchLoading = true;
    this.requestService.get(`${this.domain}/batchdelete`, {ids, ...this.defaultParams}).subscribe((data) => {
      this.batchLoading = false;
      if (data && data == 'success') {
        this.messageService.success('删除成功');
        this.checkedDatas = [];
        this.disableBatchDelete = true;
        this.freshTable();
      } else {
        this.messageService.error('删除失败');
      }
    });
  }

  update(rowData, index) {
    this.formConfig.formTitle = this.formConfig.formTitle || '更新';
    let formTitleName = this.formConfig.formTitle;
    for (const key in rowData) {
      if (formTitleName.indexOf(`{${key}}`) > -1) {
        formTitleName = formTitleName.replace(`{${key}}`, rowData[key]);
      }
    }

    this.updateBtnLoading[index] = true;
    this.requestService.get(`${this.domain}/get/${rowData[this.primaryKey]}`, this.formConfig.formParams).subscribe(data => {
      this.updateBtnLoading[index] = false;
      if (data) {
        const formConfig = {
          submitUrl: `${this.domain}/save`,
          component: this.formConfig.formComponent,
          data: {...this.formConfig.formData, ...data},
          width: this.formConfig.formWidth,
          title: formTitleName,
          okText: '更新',
          afterOk: () => {
            this.freshTable();
          }
        };

        if (this.formConfig.formType == WindowType.WINDOWS) {
          this.windowService.openWindow(formConfig);
        } else if (this.formConfig.formType == WindowType.DRAWER) {
          this.windowService.openDrawer(formConfig);
        }

      }
    });
  }

  customFields() {
    const checkValue = [];
    const options = [];
    const fixedHead = this.fixHead;
    const fields = $('dhl-titles dhl-title', this.dhltableConfig.nativeElement);
    fields.each((index, item) => {
      const show = $(item).attr('show');
      const code = $(item).attr('dataKey');
      const name = $(item).attr('name');
      const optionField = {name, value: code, disabled: false};
      if (index < fixedHead) {
        optionField.disabled = true;
      } else {
        optionField.disabled = false;
      }
      if (ObjectUtil.isHaveValue(show)) {
        if (show == 'true') {
          checkValue.push(code);
        }
      } else {
        checkValue.push(code);
      }
      options.push(optionField);
    });

    this.windowService.openWindow({
      component: FieldComponent,
      title: '选择展示的列',
      data: {options, fields: checkValue},
      afterOk: ({formData: {fields: filedList}}) => {

        const tCode = ObjectUtil.isNotEmpty(this.tableCode) ? this.tableCode : this.menu.code;

        this.fieldChange.emit(filedList);

        const fieldStr = ',' + filedList.reduce((x, y) => x + ',' + y) + ',';

        $(`dhl-title`, this.dhltableConfig.nativeElement).each((index, item) => {
          const dataKey = ',' + $(item).attr('dataKey') + ',';
          if (fieldStr.indexOf(dataKey) > -1) {
            $(item).attr('show', 'true');
          } else {
            $(item).attr('show', 'false');
          }
        });

        this.initTitleTag();
        this.drawCustomView();

        this.requestService.get(`common/savecustfields`, {
          fields: filedList,
          tableCode: tCode
        }).subscribe();

      }
    });
  }

  fresh(params) {
    this.reset();
    this.extraParams = params;
    this.freshTable();
  }

  freshTable() {

    this.clearCheckedData();

    if (this.domain) {
      setTimeout(() => {
        this.loading = true;
        const params = this.queryLocationRef ? FormUtil.getData(this.queryLocationRef.nativeElement) : {};
        this.requestService.get(
          `${this.domain}/page/${this.pageIndex}`,
          {length: this.pageSize, ...this.defaultParams, ...this.extraParams, ...params}
        ).subscribe((data) => {
          this.loading = false;
          if (data) {
            const {datas, total} = data;
            datas.forEach(item => {
              for (const checkItem of this.checkedDatas) {
                if (item[this.primaryKey] == checkItem[this.primaryKey]) {
                  item.checked = checkItem.checked;
                  item.disabled = checkItem.disabled;
                }
              }
            });
            this.datas = datas;
            this.total = total;
            this.updateBtnLoading = datas.map(() => false);
            if (datas.length > 0) {
              this.drawCustomView();
            }
          }
        });
      }, 50);
    } else {
      this.datas = [];
    }
  }


  getFixType(i) {
    const title = this.titles[i];

    if (ObjectUtil.isNotEmpty(title.headfixed)) {
      return 1;
    } else {
      if (ObjectUtil.isNotEmpty(title.tailfiexd)) {
        return 2;
      }
    }

    return 3;

  }

  delete(rowData) {
    this.requestService.post(`${this.domain}/delete/${rowData[this.primaryKey]}`, {...this.defaultParams}).subscribe((data) => {
      if (data) {
        this.messageService.success('刪除成功');
        this.freshTable();
      }
    });
  }

  customAction($action, row, btnIndex) {
    $('button', $action).trigger('click', {...row, btnIndex});
  }

  getCellValue(row, dataKey) {
    const s = dataKey.split('.');
    if (s.length > 1) {
      return row[s[0]] ? row[s[0]][s[1]] : '';
    } else {
      return row[s[0]];
    }
  }

  setCellValue(row, dataKey, value) {
    const s = dataKey.split('.');
    if (s.length > 1) {
      if (row[s[0]]) {
        row[s[0]][s[1]] = value;
      }
    } else {
      row[s[0]] = value;
    }
  }


  startUpload() {
    this.batchDeleteLoading = true;
  }

  endUpload({response: {code}}) {

    this.batchDeleteLoading = false;

    if (code == 0) {
      this.messageService.success('删除成功');
      this.freshTable();
    }

  }

  startImport() {
    this.batchImportLoading = true;
  }

  endImport({response: {code, data}}) {

    this.batchImportLoading = false;

    if (code < 0) {
      if (ObjectUtil.isNotEmpty(data) && data != 'NOTIFY') {
        this.showDownloadImportLog = true;
        this.downloadLogPath = data;
      }
    } else if (code != 'error') {
      this.messageService.success('导入成功');
      this.freshTable();
    } else {
      this.messageService.error('导入失败');
    }
  }

  downLoadImportLog() {
    this.requestService.download(`${this.domain}/download/importlog`, {filePath: this.downloadLogPath});
  }


  /**
   * 渲染自定义的component
   */
  drawCustomView(): void {

    const interval = setInterval(() => {

      if (this.templateList.length == 0) {
        return;
      }

      // const dhlTitle = this.titlesComponent;
      const n = this.titles.length;
      let titleStr = '';
      this.titles.forEach(({valueKey}, index) => {
        titleStr += valueKey + ',';
      });

      const dhlTitle = this.titlesComponent.filter(({tempRef}) => titleStr.indexOf($(tempRef.nativeElement).parent().attr('dataKey') + ',') > -1);
      dhlTitle.forEach((item, index) => {
        if (!item.viewComponent) {
          return;
        }
        const {initData, component} = item.viewComponent;


        const componentFactory = this.componentFactory.resolveComponentFactory(component);
        let data = {
          valueChange: (obj) => {
          },
          onClick: (obj) => {
          }
        };
        this.templateList.forEach((tItem, tIndex) => {
          if ((tIndex - index) % n != 0) {
            return;
          }

          // @ts-ignore
          const rowData = this.datas[parseInt(tIndex / n, 10)];
          const title = this.titles[index];

          if (initData) {
            data = initData(rowData);
          }

          const instance = tItem.createComponent(componentFactory).instance;
          if (ObjectUtil.isHaveValue(data)) {
            for (const key of Object.keys(data)) {
              const value = data[key];
              if (key == 'valueChange') {
                instance['onValueChange'] = (obj) => {
                  if (value) {
                    data.valueChange({rowData, value: obj});
                  }
                };
              } else if (key == 'onClick') {
                instance['onClick'] = (obj) => {
                  if (value) {
                    data.onClick({rowData, value: obj});
                  }
                };
              } else {
                instance[key] = value;
              }
            }
          }
        });
      });

      this.resetBtnLoading();

      clearInterval(interval);

    }, 300);
  }


  showButton($action, row) {
    const showFun = $('dhl-button', $action).data('showFun');
    if (showFun) {
      return showFun(row);
    } else {
      return true;
    }
  }

  disableButton($action, row) {
    const disableFun = $('dhl-button', $action).data('disableFun');
    if (disableFun) {
      return disableFun(row);
    } else {
      return false;
    }
  }

  loadingButton($action, row) {
    const loadFun = $('dhl-button', $action).data('isLoading');
    if (loadFun) {
      return loadFun(row);
    } else {
      return true;
    }
  }

  resetBtnLoading() {
    for (const item of this.actions) {
      const name = $(item).attr('name');
      this.actionBtnLoading[name] = [];
      for (let count = 0; count < this.pageSize; count++) {
        this.actionBtnLoading[name][count] = false;
      }
    }
  }

  onClickCell(ele, index, editRowObj, title) {

    if (title.onClick) {
      title.onClick(editRowObj);
    }

    if (this.showEditPerm && (title.edit || title.dicCode)) {
      this.editValue = this.getCellValue(editRowObj, title.dataKey);

      if (title.dicCode) {
        this.hiddenSelect = false;
      } else if (title.edit) {
        this.hiddenInput = false;
      } else {
        return;
      }

      setTimeout(() => {
        $(ele.srcElement).parent().find('input').focus();
        $(ele.srcElement).parent().find('dhl-select nz-select>div').focus();
      }, 100);


      this.editRowIndex = index;
      this.editRowObj = editRowObj;
      this.editCol = title.dataKey;
      this.dictionaryValue = this.editValue;


      this.hiddenSpan = true;
    }


  }

  selectBlur() {
    this.hiddenSelect = true;
    this.hiddenSpan = false;
  }

  stopEdit() {
    this.editRowIndex = -1;
    this.editRowObj = null;
    this.editCol = '';
    this.editValue = null;
    this.hiddenSpan = true;
  }

  keyDown(ele) {
    if (ele.code == 'Enter') {
      $(ele.srcElement).prev('span').text(this.editValue);
      const rowData = this.datas[this.editRowIndex];

      const keys = this.editCol;
      const values = this.dictionaryValue = this.editValue;

      this.setCellValue(rowData, this.editCol, this.editValue);
      this.stopEdit();

      if (this.domain) {
        this.requestService
          .post(`${this.domain}/updatefield`,
            {
              id: rowData.id,
              primaryKey: this.primaryKey,
              primaryKeyValue: rowData[this.primaryKey],
              key: keys,
              value: values
            })
          .subscribe();
      }
    }
  }

  titleSelectChange(row, dicCode) {

    const keys = this.editCol;
    const values = this.dictionaryValue;

    const selectCheckedName = this.cacheService.getOptions(dicCode)
      .filter(({value}) => value == this.dictionaryValue)[0].name;

    this.setCellValue(row, this.editCol, selectCheckedName);
    this.stopEdit();

    this.hiddenSpan = true;

    if (this.domain) {
      this.requestService
        .post(`${this.domain}/updatefield`,
          {
            id: row.id,
            primaryKey: this.primaryKey,
            primaryKeyValue: this.dictionaryValue,
            key: keys,
            value: values
          })
        .subscribe();

    }
  }


}




